package com.boost.bio.line;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

public class ComplexReadLine implements ReadLine {


    private BufferedReader bufferedReader;
    private MyInputStream myInputStream;
    private char[] splitLine;
    private char[] splitFiled;
    private CharBuffer charBuffer;

    int lineMark = 0;
    int filedMark = 0;

    public ComplexReadLine(String filePath, char[] splitLine, char[] splitFiled) throws IOException {
        this.splitFiled = splitFiled;
        this.splitLine = splitLine;
        myInputStream = new MyInputStream(filePath);
        bufferedReader = new BufferedReader(new InputStreamReader(myInputStream.getInputStream(), Charset.forName("UTF-8")));
        charBuffer = CharBuffer.allocate(10);
    }

    public ComplexReadLine(String filePath, String splitLine, String splitFiled) throws IOException {
        this(filePath, splitLine.toCharArray(), splitFiled.toCharArray());
    }

    @Override
    public List<String> read() throws IOException {
        int i = 0;
        List<String> line = new ArrayList<>();
        while ((i = bufferedReader.read()) > 0) {
            char c = (char) i;
            if (c == splitFiled[filedMark]) {
                if (filedMark == splitFiled.length - 1) {
                    charBuffer.position(charBuffer.position() - filedMark).flip();
                    line.add(charBuffer.toString());
                    charBuffer.clear();
                    filedMark = 0;
                    continue;
                } else {
                    filedMark++;
                }
            } else if (filedMark > 0) {
                filedMark = 0;
            }

            if (c == splitLine[lineMark]) {
                if (lineMark == splitLine.length - 1) {
                    charBuffer.position(charBuffer.position() - lineMark).flip();
                    line.add(charBuffer.toString());
                    lineMark = 0;
                    charBuffer.clear();
                    return line;
                } else {
                    lineMark++;
                }
            } else if (lineMark > 0) {
                lineMark = 0;
            }
            if (charBuffer.position() >= charBuffer.limit()) {
                charBuffer.flip();
                charBuffer = CharBuffer.allocate(charBuffer.capacity() << 1).put(charBuffer);
            }
            charBuffer.append(c);
        }
        return i > 0 ? line : null;
    }

    @Override
    public void close() throws IOException {
        bufferedReader.close();
    }
}
